<html>
<head><meta charset="utf-8"><title>track_caller with unwrap_or_else is not working as intended · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html">track_caller with unwrap_or_else is not working as intended</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="230921171"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230921171" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230921171">(Mar 18 2021 at 19:06)</a>:</h4>
<p>I have some code of the form</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">collections</span>::<span class="n">HashMap</span><span class="p">;</span><span class="w"></span>

<span class="cp">#[derive(Debug, PartialEq, Eq, Hash)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Key</span><span class="p">;</span><span class="w"></span>
<span class="cp">#[derive(Debug)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Value</span><span class="p">;</span><span class="w"></span>

<span class="k">struct</span> <span class="nc">Context</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">values</span>: <span class="nc">HashMap</span><span class="o">&lt;</span><span class="n">Key</span><span class="p">,</span><span class="w"> </span><span class="n">Value</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">impl</span><span class="w"> </span><span class="n">Context</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="cp">#[track_caller]</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">value_for</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">key</span>: <span class="kp">&amp;</span><span class="nc">Key</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kp">&amp;</span><span class="nc">Value</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="bp">self</span><span class="p">.</span><span class="n">values</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">).</span><span class="n">expect</span><span class="p">(</span><span class="o">&amp;</span><span class="fm">format!</span><span class="p">(</span><span class="s">"no value for key {:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">key</span><span class="p">))</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>As you can see, there's a <code>Context</code> struct that holds a mapping (in reality it<br>
holds multiple maps) and I have a utility function that gets the value for a key<br>
and unwraps the <code>Option</code>. I use <code>#[track_caller]</code> because it's the fault of the<br>
caller (or at least it's not the fault of the utility function) if the key is<br>
not there.</p>
<p>However, Clippy is not happy about this:</p>
<div class="codehilite"><pre><span></span><code>warning: use of `expect` followed by a function call
  --&gt; src/lib.rs:15:30
   |
15 |         self.values.get(key).expect(&amp;format!(&quot;no value for key {:?}&quot;, key))
   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!(&quot;no value for key {:?}&quot;, key))`
   |
   = note: `#[warn(clippy::expect_fun_call)]` on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#expect_fun_call
</code></pre></div>
<p>Unfortunately, applying the suggestion is not possible because then<br>
<code>#[track_caller]</code> won't work. Maybe that's because the panic happens inside a<br>
closure, and so the "caller" is actually the utility function?</p>
<p>What should I do to make the string formatting lazy <em>and</em> have <code>#[track_caller]</code><br>
work? Ideally it wouldn't be too complicated since I have several of these<br>
utility functions.</p>
<p>Thanks!</p>



<a name="230921224"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230921224" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230921224">(Mar 18 2021 at 19:06)</a>:</h4>
<p>Is this a bug in <code>#[track_caller]</code> or is it intended behavior?</p>



<a name="230921525"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230921525" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230921525">(Mar 18 2021 at 19:08)</a>:</h4>
<p>I don't think it's a bug, you would need to annotate the closure with <code>track_caller</code> somehow, not <code>unwrap_or_else</code></p>



<a name="230921796"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230921796" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230921796">(Mar 18 2021 at 19:10)</a>:</h4>
<p>not sure that's possible in this case because <code>unwrap_or_else</code> doesn't pass a parameter to the function, so you do need to capture local state</p>



<a name="230921803"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230921803" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230921803">(Mar 18 2021 at 19:10)</a>:</h4>
<p>Yeah, it seems like <a href="https://doc.rust-lang.org/reference/attributes/codegen.html#examples"><code>#[track_caller]</code> is supposed to work recursively</a> but there's no way to apply it to a closure.</p>



<a name="230921864"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230921864" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230921864">(Mar 18 2021 at 19:11)</a>:</h4>
<div class="codehilite"><pre><span></span><code>error[E0737]: `#[track_caller]` requires Rust ABI
  --&gt; src/lib.rs:15:45
   |
15 |         self.values.get(key).unwrap_or_else(#[track_caller] || panic!(&quot;no value for key {:?}&quot;, key))
   |                                             ^^^^^^^^^^^^^^^
</code></pre></div>



<a name="230921894"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230921894" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230921894">(Mar 18 2021 at 19:11)</a>:</h4>
<p>I guess because closures have <code>rust-call</code> ABI?</p>



<a name="230921917"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230921917" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230921917">(Mar 18 2021 at 19:11)</a>:</h4>
<p>now <em>that</em> seems like a bug</p>



<a name="230922015"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230922015" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hyd-dev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230922015">(Mar 18 2021 at 19:12)</a>:</h4>
<p><code>#[track_caller]</code> does not work on closures. There's an issue about that: <a href="https://github.com/rust-lang/rust/issues/74042">#74042</a>.</p>



<a name="230922063"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230922063" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230922063">(Mar 18 2021 at 19:12)</a>:</h4>
<p>you can <code>ok_or_else(|| format!(...)).unwrap()</code></p>



<a name="230922181"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230922181" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230922181">(Mar 18 2021 at 19:13)</a>:</h4>
<p>should make clippy happy because the <code>format!</code> will be conditional, and then <code>track_caller</code> can do its thing for the <code>unwrap</code></p>



<a name="230922670"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230922670" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230922670">(Mar 18 2021 at 19:17)</a>:</h4>
<p>it could be interesting to add <code>expect_with(msg_fn)</code> as a lazier <code>expect</code> here</p>



<a name="230922871"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230922871" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230922871">(Mar 18 2021 at 19:18)</a>:</h4>
<p><span class="user-mention silent" data-user-id="138448">cuviper</span> <a href="#narrow/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended/near/230922063">said</a>:</p>
<blockquote>
<p>you can <code>ok_or_else(|| format!(...)).unwrap()</code></p>
</blockquote>
<p>Thanks! The intent is a little less clear but it's good enough :)</p>



<a name="230922890"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230922890" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230922890">(Mar 18 2021 at 19:19)</a>:</h4>
<p><span class="user-mention silent" data-user-id="138448">cuviper</span> <a href="#narrow/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended/near/230922670">said</a>:</p>
<blockquote>
<p>it could be interesting to add <code>expect_with(msg_fn)</code> as a lazier <code>expect</code> here</p>
</blockquote>
<p>Yeah, that sounds like it might be nice.</p>



<a name="230923589"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230923589" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230923589">(Mar 18 2021 at 19:24)</a>:</h4>
<p>I'll give it a shot</p>



<a name="230930667"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/230930667" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#230930667">(Mar 18 2021 at 20:17)</a>:</h4>
<p>Ping me if you open a PR :)</p>



<a name="231144924"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/track_caller%20with%20unwrap_or_else%20is%20not%20working%20as%20intended/near/231144924" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/track_caller.20with.20unwrap_or_else.20is.20not.20working.20as.20intended.html#231144924">(Mar 20 2021 at 12:59)</a>:</h4>
<p>Related: <a href="https://github.com/rust-lang/rust/issues/74042">https://github.com/rust-lang/rust/issues/74042</a></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>